<?php

/**
 * 图片下载处理
 *
 * @author Akon(番茄红了) <aultoale@gmail.com>
 */
class CLI_Picture extends CLI
{

	/**
	 * 临时文件目录
	 *
	 * @var string
	 */
	public static $tmppath = null;

	/**
	 * 文件保存路径
	 *
	 * @var string
	 */
	public static $savepath = null;

	/**
	 * md5 目录级数
	 *
	 * @var int
	 */
	public static $md5level = 2;

	/**
	 * 下载次数限制
	 *
	 * @var int
	 */
	public static $success = 100;


	/**
	 * 变量初始化
	 *
	 * @param	none
	 * @access	public
	 * @return	void
	 * @update	date time
	*/
	public static function set_variable()
	{
		// 文件保存路径
		CLI_Picture::$savepath = IO::strip(RESPATH.'/product');
		CLI_Picture::$tmppath = IO::mkdir(CLI_Picture::$savepath.'/temp');
		CLI_Picture::$md5level = 2; // 1级目录支持约10万左右图片，2级支持约1000万左右图片

		CLI_Picture::$success = 100;

	} // end func

	/**
	 * 获取远程图片信息
	 *
	 * @param  string  $url
	 * @return string  临时文件
	 */
	public static function remoteImage($url)
	{
		// 生成图片地址
		$url = 'http://img0'.mt_rand(1, 8).'.taobaocdn.com/bao/uploaded/'.$url;

		// 下载图片数据
		$imgData = false;
		for ($i = 0; $i < 5; $i++) {
			$imgData = @file_get_contents($url);
			if ($imgData !== false) {
				break;
			}
			sleep(5); // 休息5秒
		}

		// 写入临时文件
		$tmpfile = false;
		if ($imgData !== false) {
			$tmpfile = self::$tmppath.'/'.basename($url);
			if (!is_file($tmpfile)) {
				file_put_contents($tmpfile, $imgData);
			}
		}

		return $tmpfile;
	}

	/**
	 * 保存临时文件
	 *
	 * @param  string  $tmpfile
	 * @return string  保存后的文件名
	 */
	public static function saveImage($tmpfile)
	{
		// 获取 md5 值
		$md5 = md5_file($tmpfile);

		// 生成 md5 路径
		$local = 0; $md5path = '';
		for ($i = 0; $i < self::$md5level; $i++)
		{
			$md5path .= '/'.substr($md5, $local, 2);
			$local += 2;
		}

		// 创建目录
		$savepath = IO::mkdir(self::$savepath.$md5path);

		// 存储路径及文件名
		$savefile = $savepath.'/'.$md5.strtolower(strrchr($tmpfile, '.'));

		// 重命名临时文件
		if (!is_file($savefile)) {
			$rename = @rename($tmpfile, $savefile);
			if (!$rename) {
				return false;
			}
		}

		return $savefile;
	}


	/**
	 * 下载“products”表图片
	 *
	 * @param	none
	 * @access	public
	 * @return	void
	 * @update	2011/3/29
	*/
	public static function download_products()
	{
		// 获取数量统计
		$total = DB::select(DB::expr('COUNT(*)'))
			->from('products')
			->where('pic_url', '!=', '')
			->where('image_md5', '=', '')
			->fetch_one();
		$success = self::$success;
		do {
			if ($total == 0 || $success - 100 >= $total)
			{
				break;
			}
			// 取出未下载的产品数据
			$rows = DB::select('product_id', 'pic_url')
				->from('products')
				->where('pic_url', '!=', '')
				->where('image_md5', '=', '')
				->order_by(DB::expr('RAND()'))
				->limit(100)
				->fetch_all();

			if (count($rows) == 0)
			{
				break;  // 数据为空，返回
			}
			foreach ($rows as $row)
			{
				// 获取图片信息
				$tmpfile = CLI_Picture::remoteImage($row['pic_url']);
				if ($tmpfile !== false)
				{
					// 获取 md5 值
					if ($savefile = CLI_Picture::saveImage($tmpfile))
					{
						DB::update('products')->set(array('image_md5' => basename($savefile)))->where('product_id', '=', $row['product_id'])->execute();
						echo ">";
					} else {
						echo "|";
					}
				} else {
					echo ".";
					DB::update('products')->set(array('pic_url' => ''))->where('product_id', '=', $row['product_id'])->execute();
				}
				@unlink($tmpfile); // 删除临时文件
				$success++;
			}
		} while (true);

	} // end func


	/**
	 * 下载“product_imgs”表图片
	 *
	 * @param	none
	 * @access	public
	 * @return	void
	 * @update	2011/3/29
	*/
	public static function download_products_imgs()
	{
		// 获取数量统计
		$total = DB::select(DB::expr('COUNT(*)'))
			->from('product_imgs')
			->where('pic_url', '!=', '')
			->where('image_md5', '=', '')
			->fetch_one();
		$success = self::$success;
		do {

			if ($total == 0 || $success - 100 >= $total)
			{
				break;
			}

			CLI::output("\n[$success/$total ".round($success/$total*100,1)."%] ");

			// 取出未下载的产品数据
			$rows = DB::select('id', 'url')
				->from('product_imgs')
				->where('url', '=', '')
				->where('image_md5', '=','')
				->order_by(DB::expr('RAND()'))
				->limit(100)
				->fetch_all();

			// 数据为空，返回
			if (count($rows) == 0)
			{
				break;
			}

			foreach ($rows as $row)
			{
				// 获取图片信息
				$tmpfile = CLI_Picture::remoteImage($row['url']);
				if ($tmpfile !== false)
				{
					// 获取 md5 值
					$savefile = CLI_Picture::saveImage($tmpfile);
					// 更新数据库
					$savefile && DB::update('product_imgs')->set(array('image_md5' => basename($savefile)))->where('id', '=', $row['id'])->execute();
					echo ">";
				} else {
					echo ".";
				}
				@unlink($tmpfile); // 删除临时文件
				$success++;
			}

		} while(true );
	} // end func



	/**
	 * 同步products图片
	 *
	 * @param	none
	 * @access	public
	 * @return	void
	 * @update	2011/3/29
	*/
	public static function merge_products()
	{
		DB::query(Database::UPDATE, 'ALTER TABLE `product_imgs` AUTO_INCREMENT=20000000')->execute();

		$total = DB::select(DB::expr('COUNT(*)'))
			->from('products')
			->where('image_md5', '<>','')
			->fetch_one();

		echo "\n";

		$limit = 100;
		for ($offset = 0; $offset < $total; $offset += $limit)
		{
			$rows = DB::select()
				->from('products')
				->where('image_md5', '<>', '')
				->order_by('product_id','asc')
				->limit($limit)
				->offset($offset)
				->fetch_all();
			foreach ($rows as $row)
			{
				// 查询product_imgs表
				$found = (bool) DB::select(DB::expr('COUNT(0)'))
					->from('product_imgs')
					->where('product_id','=', $row['product_id'])
					->where('image_md5', '=', $row['image_md5'])
					->fetch_one();
				if (! $found)
				{
					$data = array(
						'product_id' => $row['product_id'],
						'url' => $row['pic_url'],
						'image_md5' => $row['image_md5'],
						'position' => 0,
						'created' => time(),
						'modified' => time(),
					);
					DB::insert('product_imgs', array_keys($data))->values(array_values($data))->execute();
				}
			}
			echo ">";
		}
	} // end func



	/**
	 * 同步所有产品图片
	 *
	 * @param	none
	 * @access	public
	 * @return	void
	 * @update	2011/3/29
	*/
	public function main()
	{
		// 设置变量
		CLI_Picture::set_variable();
		// 下载产品表图片
		CLI_Picture::download_products();
		// 下载产品图片表图片
		CLI_Picture::download_products_imgs();
		// 同步图片
		CLI_Picture::merge_products();
	} // end func
}


/**
 * 下载图片数据
 *
 * @author Akon(番茄红了) <aultoale@gmail.com>


$picsMenu = <<<EOF

---------------------------

 1、下载“products”表图片

 2、下载“product_imgs”表图片

 3、下载“product_prop_imgs”表图片

 4、同步“product_imgs”表图片

 0、返回

---------------------------

请选择 (0,1,2,3,4)：
EOF;

do {
    // 显示菜单
    $input = CLI::input($picsMenu);

    // 文件保存路径
    Picture::$savepath = TRUNK_PATH.'/resources/product';
    Picture::$tmppath = EGP_Io::mkdir(Picture::$savepath.'/temp');
    Picture::$md5level = 2; // 1级目录支持约10万左右图片，2级支持约1000万左右图片

    $success = 100;

    // 下载“products”表图片
    if ($input == 1) {

        // 获取数量统计
        $total = DB::select()
            ->from('products', DB::expr('COUNT(*)'))
            ->where('pic_url IS NOT NULL')
            ->where('image_md5 IS NULL')
            ->fetchOne();

        CLI::output("\n准备开始下载，共 $total 条记录...\n");

        do {

            if ($total == 0 || $success - 100 >= $total) {
                break;
            }

            CLI::output("\n[$success/$total ".round($success/$total*100,1)."%] ");

            // 取出未下载的产品数据
            $rows = DB::select()
                ->from('products', array('product_id', 'pic_url'))
                ->where('pic_url IS NOT NULL')
                ->where('image_md5 IS NULL')
                ->order(DB::expr('RAND()'))
                ->limit(100)
                ->fetchAll();
            if (count($rows) == 0) {
                break;  // 数据为空，返回
            }

            foreach ($rows as $row) {
                // 获取图片信息
                $tmpfile = Picture::remoteImage($row['pic_url']);
                if ($tmpfile !== false) {
                    // 获取 md5 值
                    if ($savefile = Picture::saveImage($tmpfile)) {
                        DB::update('products', array('image_md5' => basename($savefile)), 'product_id='.$row['product_id']);
                        echo ">";
                    } else {
                        echo "|";
                    }
                } else {
                    echo ".";
                    DB::update('products', array('pic_url' => ''), 'product_id='.$row['product_id']);
                }
                @unlink($tmpfile); // 删除临时文件
                $success++;
            }

        } while(true );

        CLI::output("\n\n“product_imgs”表图片下载完成...\n");

    // 下载“product_imgs”表图片
    } elseif ($input == 2) {

        // 获取数量统计
        $total = DB::select()
            ->from('product_imgs', DB::expr('COUNT(*)'))
            ->where('url IS NOT NULL')
            ->where("image_md5=''")
            ->fetchOne();

        CLI::output("\n准备开始下载，共 $total 条记录...\n");

        do {

            if ($total == 0 || $success - 100 >= $total) {
                break;
            }

            CLI::output("\n[$success/$total ".round($success/$total*100,1)."%] ");

            // 取出未下载的产品数据
            $rows = DB::select()
                ->from('product_imgs', array('id', 'url'))
                ->where('url IS NOT NULL')
                ->where("image_md5=''")
                ->order(DB::expr('RAND()'))
                ->limit(100)
                ->fetchAll();
            if (count($rows) == 0) {
                break;  // 数据为空，返回
            }

            foreach ($rows as $row) {
                // 获取图片信息
                $tmpfile = Picture::remoteImage($row['url']);
                if ($tmpfile !== false) {
                    // 获取 md5 值
                    $savefile = Picture::saveImage($tmpfile);
                    // 更新数据库
                    $savefile && DB::update('product_imgs', array('image_md5' => basename($savefile)), 'id='.$row['id']);
                    echo ">";
                } else {
                    echo ".";
                }
                @unlink($tmpfile); // 删除临时文件
                $success++;
            }

        } while(true );

        CLI::output("\n\n“product_imgs”表图片下载完成...\n");

    // 下载“product_prop_imgs”表图片
    } elseif ($input == 3) {

        // 获取数量统计
        $total = DB::select()
            ->from('product_prop_imgs', DB::expr('COUNT(*)'))
            ->where('url IS NOT NULL')
            ->where('image_md5 IS NULL')
            ->fetchOne();

        CLI::output("\n准备开始下载，共 $total 条记录...\n");

        do {

            if ($total == 0 || $success - 100 >= $total) {
                break;
            }

            CLI::output("\n[$success/$total ".round($success/$total*100,1)."%] ");

            // 取出未下载的产品数据
            $rows = DB::select()
                ->from('product_prop_imgs', array('id', 'url'))
                ->where('url IS NOT NULL')
                ->where('image_md5 IS NULL')
                ->order(DB::expr('RAND()'))
                ->limit(100)
                ->fetchAll();
            if (count($rows) == 0) {
                break;  // 数据为空，返回
            }

            foreach ($rows as $row) {
                // 获取图片信息
                $tmpfile = Picture::remoteImage($row['url']);
                if ($tmpfile !== false) {
                    // 获取 md5 值
                    $savefile = Picture::saveImage($tmpfile);
                    // 更新数据库
                    $savefile && DB::update('product_prop_imgs', array('image_md5' => basename($savefile)), 'id='.$row['id']);
                    echo ">";
                } else {
                    echo ".";
                }
                @unlink($tmpfile); // 删除临时文件
                $success++;
            }

        } while(true );

        CLI::output("\n\n“product_prop_imgs”表图片下载完成...\n");

    // 同步products图片
    } elseif ($input == 4) {

        DB::query('ALTER TABLE `product_imgs` AUTO_INCREMENT=20000000');

        $total = DB::select()
            ->from('products', DB::expr('COUNT(*)'))
            ->where("image_md5<>''")
            ->fetchOne();

        echo "\n";

        $limit = 100;
        for ($offset = 0; $offset < $total; $offset += $limit) {
            $rows = DB::select()
                ->from('products')
                ->where("image_md5<>''")
                ->order('product_id ASC')
                ->limit($limit, $offset)
                ->fetchAll();
            foreach ($rows as $row) {
                // 查询product_imgs表
                $found = (bool) DB::select()
                    ->from('product_imgs', DB::expr('COUNT(0)'))
                    ->where('product_id=?', $row['product_id'])
                    ->where('image_md5=?', $row['image_md5'])
                    ->fetchOne();
                if (! $found) {
                    $data = array(
                        'product_id' => $row['product_id'],
                        'url' => $row['pic_url'],
                        'image_md5' => $row['image_md5'],
                        'position' => 0,
                        'created' => time(),
                        'modified' => time(),
                    );
                    DB::insert('product_imgs', $data);
                }
            }
            echo ">";
        }

        CLI::output("\n\n“products”表图片数据同步完成...\n");

    // 返回
    } else {
        break;
    }

    CLI::input("\n请按下回车键继续！");

} while (true);

unset($picsMenu);
 */